<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>
      
    线程编程指导 附录 A - Arisu
    
    </title>
    <link rel="shortcut icon" href="https://ushio.oss-cn-shanghai.aliyuncs.com/Arisu/Arisu_Icon.png" type="image/png" />

    
    
    <link href="atom.xml" rel="alternate" title="Arisu" type="application/atom+xml">
    <link rel="stylesheet" href="asset/css/style.min.css">
    <link rel="stylesheet" href="asset/css/doc.css">
    <script src="asset/app.js"></script>
</head>
  <body>
    <section class="hero">
      <div class="hero-head">
          <nav class="navbar" role="navigation" aria-label="main navigation">
              <div class="container">
              <div class="navbar-brand">
                
                <a target="_self" class="navbar-item " href="index.html">主页</a>
                
                <a target="_self" class="navbar-item " href="Apple.html">Apple</a>
                

                <a role="button" id="navbarSNSRssSwitchBtn" class="navbar-burger burger" aria-label="menu" aria-expanded="false" data-target="navbarSNSRssButtons">
                  <span aria-hidden="true"></span>
                  <span aria-hidden="true"></span>
                  <span aria-hidden="true"></span>
                </a>
              </div>
            
              <div id="navbarSNSRssButtons" class="navbar-menu">
                <div class="navbar-start">
                  
                </div>
            
                <div class="navbar-end">
                  <div class="navbar-item">
                    <!--buttons start-->
                    <div class="buttons">
                      
                        
                        
                        
                        
                      
                      <a href="atom.xml" target="_blank" title="RSS">
                          <span class="icon is-large has-text-black-bis">
                              <svg class="svg-inline--fa fa-rss fa-w-14 fa-lg" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="rss" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" data-fa-i2svg=""><path fill="currentColor" d="M128.081 415.959c0 35.369-28.672 64.041-64.041 64.041S0 451.328 0 415.959s28.672-64.041 64.041-64.041 64.04 28.673 64.04 64.041zm175.66 47.25c-8.354-154.6-132.185-278.587-286.95-286.95C7.656 175.765 0 183.105 0 192.253v48.069c0 8.415 6.49 15.472 14.887 16.018 111.832 7.284 201.473 96.702 208.772 208.772.547 8.397 7.604 14.887 16.018 14.887h48.069c9.149.001 16.489-7.655 15.995-16.79zm144.249.288C439.596 229.677 251.465 40.445 16.503 32.01 7.473 31.686 0 38.981 0 48.016v48.068c0 8.625 6.835 15.645 15.453 15.999 191.179 7.839 344.627 161.316 352.465 352.465.353 8.618 7.373 15.453 15.999 15.453h48.068c9.034-.001 16.329-7.474 16.005-16.504z"></path></svg><!-- <i class="fas fa-rss fa-lg"></i> -->
                          </span>
                      </a>
                    </div>
                    <!--buttons end-->

                  </div>
                </div>
                </div>
              </div>
            </nav>
      </div>

 <div class="hero-body ct-body"></div>
      
    </section>
    <section class="ct-body">
      <div class="container">
          <div class="columns is-variable bd-klmn-columns is-4 is-centered">
              <div class="column is-four-fifths">
                  <div class="post-body single-content">
                    
                    <h1 class="title">
                            线程编程指导 附录 A   
                      </h1>
                     
                    
                      <div class="media">
                            
                            <figure class="media-left">
                              <p class="image is-48x48">
                                
                                  <img class="is-rounded" src="https://ushio.oss-cn-shanghai.aliyuncs.com/Arisu/Arisu_Icon.png">
                                
                              </p>
                            </figure>
                            
                            <div class="media-content">
                              <div class="content">
                                <p>
                                 <span class="date">2020/02/25</span>
                                  <span class="tran-posted-in">posted in</span>&nbsp; 
                                  
                                      <span class="posted-in"><a href='Apple%20Developer%20Documentation.html'>Apple Developer Documentation</a></span>
                                  
                                      <span class="posted-in"><a href='%E7%BA%BF%E7%A8%8B%E7%BC%96%E7%A8%8B%E6%8C%87%E5%AF%BC.html'>线程编程指导</a></span>
                                         
                                  

                                   
                                      
                                  <br />
                                  <span class="tran-tags">Tags:</span>&nbsp;
                                  
                                    <a class="tag is-link is-light" href='tag_%E6%8A%80%E6%9C%AF%E6%96%87%E6%A1%A3.html'>#技术文档</a>
                                  
                                    <a class="tag is-link is-light" href='tag_Arisu.html'>#Arisu</a>
                                     

                                </p>
                              </div>
                            </div>
                         
                    </div>
                </div>
                  <article class="markdown-body single-content">
                    <h1><a id="%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8%E6%91%98%E8%A6%81" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>线程安全摘要</h1>
<p>本附录描述了 OS X 和 iOS 中某些关键框架的高级线程安全性。本附录中的信息可能会有所变化。</p>
<h2><a id="cocoa" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>Cocoa</h2>
<p>从多个线程使用 Cocoa 的准则包括以下内容：</p>
<ul>
<li>不可变对象通常是线程安全的。创建它们之后，您可以安全地将这些对象传递给线程和从线程传递。另一方面，可变对象通常不是线程安全的。要在线程应用程序中使用可变对象，应用程序必须适当地同步。有关更多信息，请参阅 <a href="https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html#//apple_ref/doc/uid/20000736-126010">Mutable Versus Immutable</a>。</li>
<li>许多被认为是“线程不安全”的对象在多线程中使用时只是不安全。许多这些对象可以在任何线程中使用，只要它一次只有一个线程即可。特别限制于应用程序主线程的对象将被调出。</li>
<li>应用程序的主线程负责处理事件。尽管如果事件路径中涉及其他线程，Application Kit 仍可继续工作，但操作可能会不按顺序进行。</li>
<li>如果要使用线程绘制图案到视图，请将所有绘图代码括在 <code>NSView</code> 的 <code>lockFocusIfCanDraw</code> 和 <code>unlockFocus</code> 方法之间。</li>
<li>要将 POSIX 线程与 Cocoa 一起使用，必须首先将 Cocoa 置于多线程模式。有关更多信息，请参阅<a href="https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html#//apple_ref/doc/uid/20000738-125024">在 Cocoa 应用程序中使用 POSIX 线程</a>。</li>
</ul>
<h3><a id="foundation%E6%A1%86%E6%9E%B6%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>Foundation 框架线程安全</h3>
<p>有一种误解，认为 Foundation 框架是线程安全的，而 Application Kit 框架则不是。不幸的是，这是一个粗略的概括，有些误导。每个框架都有线程安全的区域和非线程安全的区域。以下部分描述了 Foundation 框架的一般线程安全性。</p>
<h4><a id="%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8%E7%B1%BB%E5%92%8C%E5%87%BD%E6%95%B0" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>线程安全类和函数</h4>
<p>以下类和函数通常被认为是线程安全的。您可以在不首先获取锁定的情况下从多个线程使用相同的实例。</p>
<pre><code class="language-objectivec">NSArray                                 NSAssertionHandler
NSAttributedString                      NSBundle
NSCalendar                              NSCalendarDate
NSCharacterSet                          NSConditionLock
NSConnection                            NSData
NSDate                                  NSDateFormatter
NSDecimal functions                     NSDecimalNumber
NSDecimalNumberHandler                  NSDeserializer
NSDictionary                            NSDistantObject
NSDistributedLock                       NSDistributedNotificationCenter
NSException                             NSFileManager
NSFormatter                             NSHost
NSJSONSerialization                     NSLock
NSLog/NSLogv                            NSMethodSignature
NSNotification                          NSNotificationCenter
NSNumber                                NSNumberFormatter
NSObject                                NSOrderedSet
NSPortCoder                             NSPortMessage
NSPortNameServer                        NSProgress
NSProtocolChecker                       NSProxy
NSRecursiveLock                         NSSet
NSString                                NSThread
NSTimer                                 NSTimeZone
NSUserDefaults                          NSValue
NSXMLParser
Object allocation and retain count functions
Zone and memory functions
</code></pre>
<h4><a id="%E7%BA%BF%E7%A8%8B%E4%B8%8D%E5%AE%89%E5%85%A8%E7%9A%84%E7%B1%BB" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>线程不安全的类</h4>
<p>以下类和函数通常不是线程安全的。在大多数情况下，只要您一次只使用一个线程，就可以从任何线程使用这些类。查看课程文档以获取更多详细信息。</p>
<pre><code class="language-objectivec">NSArchiver                           NSAutoreleasePool
NSCoder                              NSCountedSet
NSEnumerator                         NSFileHandle
NSHashTable functions                NSInvocation
NSMapTable functions                 NSMutableArray
NSMutableAttributedString            NSMutableCharacterSet
NSMutableData                        NSMutableDictionary
NSMutableOrderedSet                  NSMutableSet
NSMutableString                      NSNotificationQueue
NSPipe                               NSPort
NSProcessInfo                        NSRunLoop
NSScanner                            NSSerializer
NSTask                               NSUnarchiver
NSUndoManager
User name and home directory functions
</code></pre>
<p>请注意，尽管 <code>NSArchiver</code>，<code>NSCoder</code> 和 <code>NSEnumerator</code> 对象本身是线程安全的，但它们在此处列出，因为在使用它们时更改由它们包装的数据对象是不安全的。例如，对于归档程序，更改正在归档的对象图是不安全的。对于枚举器，任何线程更改枚举集合都是不安全的。</p>
<h4><a id="%E4%B8%BB%E7%BA%BF%E7%A8%8B%E4%BB%85%E9%99%90%E7%B1%BB" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>主线程仅限类</h4>
<p>必须仅从应用程序的主线程使用以下类。</p>
<pre><code class="language-objectivec">NSAppleScript
</code></pre>
<h4><a id="%E5%8F%AF%E5%8F%98%E4%B8%8E%E4%B8%8D%E5%8F%AF%E5%8F%98" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>可变与不可变</h4>
<p>不可变对象通常是线程安全的跑；一旦创建它们，就可以安全地将这些对象传递给线程和从线程传递。当然，在使用不可变对象时，您仍需要记住正确使用引用计数。如果您不恰当地释放了您未保留的对象，则可能会在以后导致异常。</p>
<p>可变对象通常不是线程安全的。要在线程应用程序中使用可变对象，应用程序必须使用锁同步对它们的访问。（有关更多信息，请参阅<a href="https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html#//apple_ref/doc/uid/10000057i-CH8-SW2">原子操作</a>）。通常，当涉及到突变时，集合类（例如，<code>NSMutableArray</code>，<code>NSMutableDictionary</code>）不是线程安全的。也就是说，如果一个或多个线程正在更改同一阵列，则可能会出现问题。您必须锁定发生读写的位置，以确保线程安全。</p>
<p>即使一个方法声称返回一个不可变对象，你也不应该简单地假设返回的对象是不可变的。根据方法实现，返回的对象可能是可变的或不可变的。例如，返回类型为 <code>NSString</code> 的方法可能实际上由于其实现而返回 <code>NSMutableString</code>。如果你想保证你拥有的对象是不可变的，你应该制作一个不可变的副本。</p>
<h4><a id="%E9%87%8D%E5%85%A5" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>重入</h4>
<p>仅当操作“调出”到同一对象或不同对象中的其他操作时，才可以进行重入。保留和释放物体是一种有时被忽视的“召唤”。</p>
<p>下表列出了可明确重入的 Foundation 框架部分。所有其他类可能是也可能不是可重入的，或者它们将来可能会被重入。对于重入的完整分析从未进行过，此列表可能并非详尽无遗。</p>
<pre><code class="language-objectivec">Distributed Objects       NSConditionLock
NSDistributedLock         NSLock
NSLog/NSLogv              NSNotificationCenter
NSRecursiveLock           NSRunLoop
NSUserDefaults
</code></pre>
<h4><a id="%E7%B1%BB%E5%88%9D%E5%A7%8B%E5%8C%96" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>类初始化</h4>
<p>objectivec 运行时系统在类接收任何其他消息之前向每个类对象发送 <code>initialize</code> 消息。这使类有机会在使用之前设置其运行时环境。在多线程应用程序中，运行时保证只有一个线程 - 恰好将第一个消息发送到类的线程 - 执行 <code>initialize</code> 方法。如果第二个线程在第一个线程仍处于 <code>initialize</code> 方法时尝试向该类发送消息，则第二个线程将阻塞，直到 <code>initialize</code> 方法完成执行。同时，第一个线程可以继续调用类上的其他方法。<code>initialize</code> 方法不应该依赖于第二个线程调用类的方法；如果是这样，两个线程就会陷入僵局。</p>
<p>由于 OS X 版本 10.1.x 及更早版本中的错误，线程可以在另一个线程完成执行该类的 <code>initialize</code> 方法之前将消息发送到类。然后，线程可以访问尚未完全初始化的值，可能会使应用程序崩溃。如果遇到此问题，则需要引入锁以防止在初始化之后访问值，或者强制类在变为多线程之前初始化自身。</p>
<h4><a id="%E8%87%AA%E5%8A%A8%E9%87%8A%E6%94%BE%E6%B1%A0" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>自动释放池</h4>
<p>每个线程都维护自己的 <code>NSAutoreleasePool</code> 对象堆栈。Cocoa 期望在当前线程的堆栈上始终有一个自动释放池。如果池不可用，则不会释放对象并导致内存泄漏。在基于 Application Kit 的应用程序的主线程中自动创建和销毁 <code>NSAutoreleasePool</code> 对象，但是在使用 Cocoa 之前，辅助线程（以及仅基于 Foundation 的应用程序）必须创建自己的对象。如果你的线程很长并且可能生成大量自动释放的对象，你应该定期销毁并创建自动释放池（就像主要线程上的Application Kit一样）；否则，自动释放的对象会累积，并且您的内存占用会增加。如果您的分离线程不使用 Cocoa，则无需创建自动释放池。</p>
<h4><a id="%E8%BF%90%E8%A1%8C%E5%BE%AA%E7%8E%AF%EF%BC%88run-loops%EF%BC%89" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>运行循环（Run Loops）</h4>
<p>每个线程都有一个且只有一个运行循环。但是，每个运行循环对应于每个线程都有自己的一组输入模式，用于确定运行循环时哪些输入源被监听。在一个运行循环中定义的输入模式不会影响在另一个运行循环中定义的输入模式，即使它们可能具有相同的名称。
如果您的应用程序基于 Application Kit，则自动运行主线程的运行循环，但是辅助线程（以及仅基于 Foundation 的应用程序）必须自己运行运行循环。如果分离的线程没有进入运行循环，则一旦分离的方法完成执行，线程就会退出。</p>
<p>尽管有一些例外，<code>NSRunLoop</code> 类不是线程安全的。您应该只从拥有它的线程调用此类的实例方法。</p>
<h3><a id="application-kit-framework%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>Application Kit Framework 线程安全</h3>
<p>以下部分描述了 Application Kit 框架的一般线程安全性。</p>
<h4><a id="%E7%BA%BF%E7%A8%8B%E4%B8%8D%E5%AE%89%E5%85%A8%E7%B1%BB" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>线程不安全类</h4>
<p>以下类和函数通常不是线程安全的。在大多数情况下，只要您一次只使用一个线程，就可以从任何线程使用这些类。查看课程文档以获取更多详细信息。</p>
<ul>
<li><code>NSGraphicsContext</code>。有关更多信息，请参阅<a href="https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html#//apple_ref/doc/uid/10000057i-CH12-126712">NSGraphicsContext限制</a>。</li>
<li><code>NSImage</code>。有关更多信息，请参阅<a href="https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html#//apple_ref/doc/uid/10000057i-CH12-126728">NSImage 限制</a>。</li>
<li><code>NSResponder</code>。</li>
<li><code>NSWindow</code> 及其所有后代。有关更多信息，请参阅 <a href="https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html#//apple_ref/doc/uid/10000057i-CH12-123427">NSView Restrictions</a>。</li>
</ul>
<h4><a id="%E4%B8%BB%E7%BA%BF%E7%A8%8B%E4%BB%85%E9%99%90%E7%B1%BB" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>主线程仅限类</h4>
<p>必须仅从应用程序的主线程使用以下类。</p>
<ul>
<li>NSCell 及其所有后代。</li>
<li>NSView 及其所有后代。有关更多信息，请参阅 <a href="https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html#//apple_ref/doc/uid/10000057i-CH12-123427">NSView Restrictions</a>。</li>
</ul>
<h4><a id="window%E9%99%90%E5%88%B6" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>Window 限制</h4>
<p>您可以在辅助线程上创建一个窗口。Application Kit 确保在主线程上释放与窗口关联的数据结构，以避免竞争条件。窗口对象可能会在同时处理大量窗口的应用程序中泄漏。</p>
<p>您可以在辅助线程上创建模态窗口。应用程序工具包在主线程运行模态循环时阻止调用辅助线程。</p>
<h4><a id="%E4%BA%8B%E4%BB%B6%E5%A4%84%E7%90%86%E9%99%90%E5%88%B6" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>事件处理限制</h4>
<p>应用程序的主线程负责处理事件。主线程是 在 <code>NSApplication</code> 的 <code>run</code> 方法中被阻塞的线程，通常在应用程序的 <code>main</code> 函数中调用。如果事件路径中涉及其他线程，则 Application Kit 将继续工作，但操作可能会不按顺序发生。例如，如果两个不同的线程正在响应键事件，则可能无序地接收键。通过让主线程处理事件，您可以获得更一致的用户体验。收到后，如果需要，可以将事件分派给辅助线程以进行进一步处理。</p>
<p>您可以从辅助线程调用 <code>NSApplication</code> 的 <code>postEvent:atStart:</code> 方法，将事件发布到主线程的事件队列。但是，不保证用户输入事件的顺序。应用程序的主线程仍负责处理事件队列中的事件。</p>
<h4><a id="%E7%BB%98%E5%9B%BE%E9%99%90%E5%88%B6" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>绘图限制</h4>
<p>使用图形函数和类（包括 <code>NSBezierPath</code> 和 <code>NSString</code> 类）绘制时，Application Kit 通常是线程安全的。以下各节介绍了使用特定类的详细信息。有关图纸和螺纹的更多信息，请参阅 <a href="https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CocoaDrawingGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40003290">Cocoa Drawing Guide</a>。</p>
<h5><a id="nsview%E9%99%90%E5%88%B6" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>NSView 限制</h5>
<p><code>NSView</code> 类通常不是线程安全的。您应该仅从应用程序的主线程在 <code>NSView</code> 对象上创建，销毁，调整大小，移动和执行其他操作。只要您通过调用 <code>lockFocusIfCanDraw</code> 和 <code>unlockFocus</code> 来绘制绘图调用，从辅助线程绘制就是线程安全的。
如果应用程序的辅助线程想要在主线程上重写部分视图，则不能使用 <code>display</code>，<code>setNeedsDisplay:</code>，<code>setNeedsDisplayInRect:</code> 或 <code>setViewsNeedDisplay:</code> 等方法执行此操作。相反，它应该向主线程发送消息或使用 <code>performSelectorOnMainThread:withObject:waitUntilDone:</code> 方法调用这些方法。
视图系统的图形状态（gstates）是每个线程。使用图形状态曾经是一种在单线程应用程序上实现更好绘图性能的方法，但现在已不再适用。不正确使用图形状态实际上会导致绘图代码的效率低于在主线程中绘制的效率。</p>
<h5><a id="nsgraphicscontext%E9%99%90%E5%88%B6" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>NSGraphicsContext 限制</h5>
<p><code>NSGraphicsContext</code> 类表示底层图形系统提供的绘图上下文。每个 <code>NSGraphicsContext</code> 实例都拥有自己独立的图形状态：坐标系，剪切，当前字体等。在每个 NSWindow 实例的主线程上自动创建该类的实例。如果从辅助线程执行任何绘制，则会专门为该线程创建新的 <code>NSGraphicsContext</code> 实例。
如果从辅助线程执行任何绘制，则必须手动刷新绘图调用。Cocoa 不会自动使用从辅助线程绘制的内容更新视图，因此在完成绘图时需要调用 <code>NSGraphicsContext</code> 的 <code>flushGraphics</code> 方法。如果您的应用程序仅从主线程中提取内容，则无需刷新绘图调用。</p>
<h5><a id="nsimage%E9%99%90%E5%88%B6" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>NSImage 限制</h5>
<p>一个线程可以创建一个 <code>NSImage</code> 对象，绘制到图像缓冲区，并将其传递给主线程进行绘制。底层图像缓存在所有线程之间共享。有关图像以及缓存的工作原理的详细信息，请参阅 <a href="https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CocoaDrawingGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40003290">Cocoa绘图指南</a>。</p>
<h3><a id="cocoa-data%E6%A1%86%E6%9E%B6" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>Cocoa Data 框架</h3>
<p>核心数据框架通常支持线程，尽管有一些适用的注意事项。有关这些警告的信息，请参阅 <a href="https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreData/index.html#//apple_ref/doc/uid/TP40001075">Core Data Programming Guide</a> 中的“核心数据并发”。</p>
<h2><a id="core-foundation" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>Core Foundation</h2>
<p>Core Foundation 具有足够的线程安全性，如果您小心编程，则不应遇到与竞争线程相关的任何问题。它在常见情况下是线程安全的，例如查询，保留，释放和传递不可变对象时。即使可能从多个线程查询的中央共享对象也是可靠的线程安全的。</p>
<p>与 Cocoa 一样，Core Foundation 在对象或其内容的突变方面不是线程安全的。例如，正如您所料，修改可变数据或可变数组对象不是线程安全的，但也不是修改不可变数组内的对象。其中一个原因是性能，这在这些情况下至关重要。而且，通常不可能在该水平上实现绝对的安全性。例如，您不能排除因保留从集合中获取的对象而导致的不确定行为。在调用保留包含的对象之前，可能会释放集合本身。</p>
<p>在要从多个线程访问 Core Foundation 对象并进行变更的情况下，您的代码应通过在接入点使用锁来防止同时访问。例如，枚举 Core Foundation 数组对象的代码应该使用枚举块周围的相应锁定调用来防止其他人改变数组。</p>
<div style="padding-top:25px;">
    <div style="float:left;">
        <a style="text-decoration:none" href="%E5%90%8C%E6%AD%A5.html">&laquo; 上一章：同步</a>
    </div>
</div>

                  </article>
                  <div class="comments-wrap">
                    <div class="share-comments">
                      

                      

                      
                    </div>
                  </div><!-- end comments wrap -->
              </div>
            </div><!-- end columns -->
      </div><!-- end container -->
    </section>



    <footer class="footer">
        <div class="content has-text-centered">
          <p>
              Copyright &copy; 2019
              Powered by <a target="_blank" href="http://www.mweb.im">MWeb</a>,&nbsp; 
              Theme used <a target="_blank" href="https://bulma.io/">Bulma CSS</a>.
          </p>
        </div>
      </footer>



  













<script src="asset/prism.js"></script>



  
    




  </body>
</html>
